package com.itsccn.springaop.aop;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.alibaba.fastjson.JSON;


/**
 * @author Administrator
 *
 */
/** 
* @ClassName: Advices 
* @Description: TODO(Spring AOP 实现) 
* @author 孙晨
* @date 2016年12月16日 下午5:13:50 
*  
*/
@Component
@Aspect
public class Advices {
	Logger log = Logger.getLogger(Advices.class);

	/**
	 * 定义切入点 execution(* com.itsccn.springaop.controller.*.*(..)) controller 包下面 所有返回值 参数的方法 被代理
	 */
	@Pointcut("execution(* com.itsccn.springaop.controller.*.*(..))")
	private void exceptionMethod() {
	}

	/**
	 * @annotation(com.itsccn.springaop.annotation.Log)  所有 使用了@Log 注解的方法
	 */
	@Pointcut("execution(* com.itsccn.springaop.controller.*.*(..) ) || @annotation(com.itsccn.springaop.annotation.Log)")
	private void afterMethod() {
	}

	/** 当方法执行过程中 抛出异常是会被代理 这边throw new Exception(e); 会被DefaultException 拦截到统一处理 （这边不抛出异常也可以拦截大）
	 * @param jp
	 * @param e
	 * @throws Exception
	 */
	@AfterThrowing(pointcut = "exceptionMethod()", throwing = "e")
	public void afterThrowing(JoinPoint jp, Throwable e) throws Exception {
		throw new Exception(e);
	}

	/** 方法执行完后  打印出请求日志
	 * @param jp
	 * @throws Exception
	 */
	@After(value = "afterMethod()")
	public void after(JoinPoint jp) throws Exception {
		ServletRequestAttributes sra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = sra.getRequest();
		String url = request.getRequestURL().toString();
		String method = request.getMethod();
		String uri = request.getRequestURI();
		Map<String, String[]> queryString = request.getParameterMap();
		log.info("请求开始, 各个参数, url: {" + url + "}, method: {" + method + "}, uri: {" + uri + "}, params: {" +JSON.toJSONString(queryString)+ "}");
	}
}
